#ifndef __M_SS_H__
#define __M_SS_H__
#include "util.hpp"
#include "logerr.hpp"
typedef enum
{
    UNLOGIN,
    LOGIN
} ss_statu;

class session
{
private:
    uint64_t _uid;
    uint64_t _ssid;
    webserve_t::timer_ptr _time; // 有没有定时任务 有的话就是短链接 没有的话时长连接
    ss_statu _status;

public:
    session(uint64_t ssid) : _ssid(ssid) { DBG_LOG("SESSION %p 被创建！！", this); }
    ~session() { DBG_LOG("SESSION %p 被释放！！", this); }
    uint64_t get_uid() { return _uid; };
    void set_uid(uint64_t uid) { _uid = uid; };
    uint64_t get_ssid() { return _ssid; };
    void set_ssid(uint64_t ssid) { _ssid = ssid; };
    void set_status(ss_statu status) { _status = status; };
    ss_statu get_status() { return _status; };
    bool check_time_is_empty() { return _time.get() == nullptr; };
    webserve_t::timer_ptr get_timer() { return _time; };
    void set_time(webserve_t::timer_ptr time) { _time = time; };
};
#define SESSION_TIMEOUT 30000
#define SESSION_FOREVER -1
using session_ptr = std::shared_ptr<session>;
class session_manager
{
private:
    session_ptr _sessionptr;
    std::mutex _mutex;
    uint64_t _sessionid; // 分配id的计数器
    std::unordered_map<uint64_t, session_ptr> _sessioncontain;
    webserve_t *_wbr; // 用来设置我们的定时任务
public:
    session_manager(webserve_t *wbr)
        : _wbr(wbr), _sessionid(1)
    {
        DBG_LOG("session manager create success");
    }
    ~session_manager()
    {
        DBG_LOG("session manager delete success");
    }
    session_ptr create_session(uint64_t uid, ss_statu statu)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        {
            session_ptr temsession(new session(_sessionid));
            temsession->set_ssid(_sessionid);
            temsession->set_status(statu);
            temsession->set_uid(uid);
            _sessioncontain.insert(std::make_pair(_sessionid,temsession));
            _sessionid++;
            return temsession;
        }
    }
    session_ptr get_session_by_ssid(uint64_t ssid)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        auto pos = _sessioncontain.find(ssid);
        if (pos == _sessioncontain.end())
        {
            return session_ptr();
        }
        return pos->second;
    }
    void remove_session(uint64_t ssid)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        _sessioncontain.erase(ssid);
    }
    void append_session(const session_ptr &ssp)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        _sessioncontain.insert(std::make_pair(ssp->get_ssid(), ssp));
    }

    void set_session_expire_time(uint64_t ssid, int ms)
    {
       // DBG_LOG("SSID = %s",std::to_string(ssid).c_str());
        //DBG_LOG("ms = %d",ms);
        // 此时有几种情况 如果时登录 注册此时我们采用http
        // 我们此时设置我们的过期时间
        // 如果我们进入游戏大厅 和 游戏房间此时我们时wessocket连接 我们的session此时时永久的我们不做处理
        session_ptr cursessionptr = get_session_by_ssid(ssid);
        if (cursessionptr.get() == nullptr)
        {
            DBG_LOG("没有改会话");
            return;
        }
        webserve_t::timer_ptr tp = cursessionptr->get_timer();

        if (tp.get() == nullptr && ms == SESSION_FOREVER)
        {
            // 1. 在session永久存在的情况下，设置永久存在
            return;
        }
        else if (tp.get() == nullptr && ms != SESSION_FOREVER)
        {
            // 2. 在session永久存在的情况下，设置指定时间之后被删除的定时任务
            webserve_t::timer_ptr tmp_tp = _wbr->set_timer(ms,
                                                           std::bind(&session_manager::remove_session, this, ssid));
            cursessionptr->set_time(tmp_tp);
        }
        else if (tp.get() != nullptr && ms == SESSION_FOREVER)
        {
            // http协议情况下 想把会话时间设置为永久的
            tp->cancel();
            // 置空代表没有定时任务 就是永久的session了
            cursessionptr->set_time(webserve_t::timer_ptr());
            // 再次进行设置
            _wbr->set_timer(0, std::bind(&session_manager::append_session, this, cursessionptr));
        }
        else if (tp.get() != nullptr && ms != SESSION_FOREVER)
        {
            // http协议情况下 想把会话时间设置为永久的
            tp->cancel();
            // 置空代表没有定时任务 就是永久的session了
            cursessionptr->set_time(webserve_t::timer_ptr());
            // 再次进行设置
            _wbr->set_timer(0, std::bind(&session_manager::append_session, this, cursessionptr));

            // 此时我们直接重置我们的定时任务 就是删除我们的session
            webserve_t::timer_ptr tem1ptr = _wbr->set_timer(ms,
                                                            std::bind(&session_manager::remove_session, this, ssid));
            cursessionptr->set_time(tem1ptr);
        }
        return;
    }




};
#endif